home *** CD-ROM | disk | FTP | other *** search
/ World of Education / World of Education.iso / world_p / pcshx10b.zip / PCSHX10B.EXE / GNUFGREP.EXE / GREPDOCS.EXE / GLOBARGV.C < prev    next >
C/C++ Source or Header  |  1990-08-31  |  4KB  |  161 lines

  1. /*-
  2.  *      int globargv(&argc, &argv, globber)
  3.  *
  4.  * General purpose globbing routine for argv lists.  You can call
  5.  * globargv() near the beginning of a main program to glob the program
  6.  * argument list.  The new argv list will be dynamically allocated
  7.  * and NULL terminated.
  8.  *
  9.  * `globber' is a function declared as `char **globber(char *pattern)',
  10.  * and should behave the way GNU glob_filename() does.  That is as follows:
  11.  *      -- If there is a memory allocation overflow, return NULL
  12.  *      -- If there is a file access error (ENOENT, for instance),
  13.  *         return (char **) -1    [globargv() considers a file access
  14.  *         error to be equivalent to a `no match']
  15.  *      -- If there is no match, return a pointer to a NULL pointer
  16.  *      -- Otherwise, return a pointer to a NULL terminated array of
  17.  *         pointers to the globbing matches
  18.  *
  19.  * Note that globargv() runs an in-place sort on the array returned by
  20.  * globber().  I think this is unlikely to be a problem.
  21.  *
  22.  * The return value of globargv() is -1 if a memory allocation error
  23.  * occurred, otherwise 0.  Only in the latter case are argc and argv
  24.  * affected.
  25.  *
  26.  * Written by Barry Schwartz, 29 August 1990.
  27.  */
  28.  
  29. #include <stdlib.h>
  30. #include <stddef.h>
  31. #include <string.h>
  32. #include <search.h>
  33.  
  34.  
  35.  
  36. /* Comparison function for qsort() */
  37. static int
  38. arg_compare(const char **arg1, const char **arg2)
  39. {
  40.     /* Use the Microsoft library stricmp() function, which is a case
  41.      * insensitive version of strcmp */
  42.     return stricmp(*arg1, *arg2);
  43. }
  44.  
  45.  
  46.  
  47. /*-
  48.  *       0 --> success
  49.  *      -1 --> memory allocation overflow
  50.  */
  51. int
  52. globargv(int *argc, char ***argv, char **(*globber)(char *))
  53. {
  54.     char **p;
  55.     char **newargv;
  56.     char **globber_output;
  57.     unsigned int number_of_new_args;
  58.     int newargc;
  59.     int oldarg_index;
  60.  
  61.     newargv = malloc(2 * sizeof(char *));
  62.     if (!newargv)
  63.     goto cannot_allocate;
  64.     newargv[0] = (*argv)[0];    /* Program name */
  65.     newargv[1] = NULL;
  66.     newargc = 1;
  67.  
  68.     for (oldarg_index = 1; oldarg_index != *argc; ++oldarg_index)
  69.     {
  70.     globber_output = (*globber)((*argv)[oldarg_index]);
  71.     if (globber_output == NULL)
  72.         goto cannot_allocate;
  73.  
  74.     /* Count the number of new arguments (zero if no match or
  75.          * file error occurred) */
  76.     number_of_new_args = 0;
  77.     if (globber_output != (char **) -1)
  78.         for (p = globber_output; *p; ++p)
  79.         ++number_of_new_args;
  80.  
  81.     /* Sort the globber output in case-insensitive ascending
  82.          * ASCII order */
  83.     if (number_of_new_args > 1)
  84.         qsort(globber_output, number_of_new_args,
  85.                   sizeof(globber_output[0]), arg_compare);
  86.  
  87.     /* Incorporate the new arguments into the new argv list */
  88.     if (number_of_new_args == 0)
  89.     {
  90.         newargv = realloc(newargv, (newargc + 2) * sizeof(char *));
  91.         if (!newargv)
  92.         goto cannot_allocate;
  93.         newargv[newargc++] = (*argv)[oldarg_index];
  94.         newargv[newargc] = NULL;
  95.     }
  96.     else
  97.     {
  98.         newargv = realloc(newargv,
  99.             (newargc + number_of_new_args + 1) * sizeof(char *));
  100.         if (!newargv)
  101.         goto cannot_allocate;
  102.         for (p = globber_output; *p; ++p)
  103.         newargv[newargc++] = *p;
  104.         newargv[newargc] = NULL;
  105.     }
  106.     }
  107.  
  108.     /* Successful return */
  109.     *argv = newargv;
  110.     *argc = newargc;
  111.     return 0;
  112.  
  113. cannot_allocate:
  114.     /* Error occurred while allocating memory.  Any blocks already
  115.      * allocated should have been freed (by realloc()) when the error
  116.      * occurred. */
  117.     return -1;
  118. }
  119.  
  120.  
  121.  
  122. #ifdef TEST
  123.  
  124.  
  125. #include <stdio.h>
  126.  
  127.  
  128. int
  129. main(int argc, char **argv)
  130. {
  131.     extern int backslash_same_as_slash;
  132.     char **glob_filename(char *);
  133.  
  134.     backslash_same_as_slash = 1;
  135.     switch (globargv(&argc, &argv, glob_filename))
  136.     {
  137.     case -1:
  138.     fprintf(stderr, "memory allocation error, return value -1\n");
  139.     return -1;
  140.  
  141.     case 0:
  142.     {
  143.         int i;
  144.  
  145.         for (i = 0; i != argc; ++i)
  146.         printf("%s ", argv[i]);
  147.     }
  148.     putchar('\n');
  149.     if (argv[argc] != NULL)
  150.         fprintf(stderr, "argv[argc] is not NULL\n");
  151.     return 0;
  152.  
  153.     default:
  154.     fprintf(stderr, "illegal return value\n");
  155.     return 1;
  156.     }
  157. }
  158.  
  159.  
  160. #endif
  161.